Skip to content

feat(build): emit the routed CLI into host artifacts as bin/<name>.mjs (#387) - #419

Merged
ScriptedAlchemy merged 5 commits into
mainfrom
fix/387-artifact-routed-cli
Sep 3, 2026
Merged

feat(build): emit the routed CLI into host artifacts as bin/<name>.mjs (#387)#419
ScriptedAlchemy merged 5 commits into
mainfrom
fix/387-artifact-routed-cli

Conversation

@ScriptedAlchemy

@ScriptedAlchemy ScriptedAlchemy commented Sep 3, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #387. The routed CLI (src/cli/**) was compiled only into the npm package build (dist/bin/<name>.js), so a plugin installed from a host artifact had skills telling agents to run <name> status and a script route meant to forward to it, but nothing to forward to.

Decision (emission, framework model): the routed CLI is the same class of surface as scripts/*.mjs — a self-contained Node module that only needs the artifact root to be a plain directory Node executes from, which every host already relies on for mcp/ and scripts/. So the build now emits the compiled command graph into every selected host artifact whose adapter publishes a new cli capability, as <target>/bin/<plugin-name>.mjs (+ bin/<plugin-name>-flight.mjs react-server worker when any command renders), invoked as node <plugin-root>/bin/<plugin-name>.mjs <command> [args]. All five built-in targets (claude, codex, cursor, portable, plugin) publish the capability. The package build's bin emission is unchanged.

  • Capability gate — new cli capability row (cliBinCapability) on every built-in adapter; the composite plugin adapter unions the three hosts. A target publishing no row reads as honest unavailable: the bin is omitted, inspect lists a cli component skipped as unsupported-capability, and source validation reports AB4765 (warning). Registration rejects an adapter that claims a supported cli capability without a cliBin artifact layout.
  • Layout / validation / inventoryTargetArtifactLayout.cliBin ({ directory: 'bin', allowedSuffixes: ['.mjs'] }) on the standard, portable, and plugin layouts; artifact ownership validation admits it; the manifest records both files with bundle provenance naming every command route; inspect --bundler dumps each target's bin composition; BuildResult.compiledCliBins reports them.
  • CollisionAB4766 (build error) when a target plan already emits bin/<name>.mjs / -flight.mjs (e.g. a Claude claude.bin directory shipping the same file name).
  • Reaching it — script routes use the documented sibling convention new URL('../bin/<plugin-name>.mjs', import.meta.url)spawn(process.execPath, [...]); skills/hooks use the plugin-root token (${CLAUDE_PLUGIN_ROOT}/bin/<plugin-name>.mjs). The composite bundle's AGENTS.md documents the shared executable.
  • State anchor — the artifact bin (and its worker) anchor workspace-durable state on the artifact root (parent of bin/), the same fallback as the MCP worker beside it, so a co-installed CLI and server share one store; the npm bin keeps its cwd fallback (stateFallback option on the generated entry shells).
  • Docs: docs/entry-conventions.md (new “The routed CLI inside host artifacts” section), docs/framework-mode.md, docs/diagnostics.md (AB4765AB4766, verified unused in origin/main and every open PR), packages/agent-bundle/README.md; changeset .changeset/387-artifact-routed-cli.md (agent-bundle minor).

Evidence

Local gates on this branch (worktree at origin/main 56b77db):

  • pnpm typecheck — clean.
  • pnpm lint — 0 errors / 0 warnings (1048 files).
  • pnpm test:unit — 2728 passed, 2 failed → both rerun in isolation: mcp-probe-service passes; native-claude-contract › fails closed when the candidate plugin… times out at its 5 s budget identically on pristine origin/main in this environment (stash-verified), so it is pre-existing and unrelated.
  • pnpm test:route-unit — 37/37. pnpm test:projection — 66/66.
  • pnpm build && pnpm test:integration:run — 78 files, 950 passed, 0 failed, 32 skipped (includes artifact validation and host proofs, plus the new artifact-cli-bin.test.ts).

Test plan

  • tests/artifact-cli-bin.test.ts (integration): one fixture (plain + rendered CLI routes, a plain script route spawning the sibling bin) built for claude, codex, cursor, portable, plugin and a custom legacy-host adapter without the capability. Asserts per capable target: bin/<name>.mjs + -flight.mjs exist, node bin/<name>.mjs status ticket-7 --json prints the routed JSON, help/version/rendered Markdown/--json/exit-2 usage on the same bin, self-contained (no agent-bundle/cli-entry or agent-bundle/meta import left); legacy-host has no bin/ but keeps scripts/; exactly one AB4765 warning; script route forwards argv through the sibling bin; composite AGENTS.md documents it; manifest bundle provenance names src/cli/status.ts and src/cli/report.tsx; validateArtifact reports no errors; inspect selects the cli component with supported evidence on claude and skips it unsupported-capability on legacy-host; inspect --bundler lists 10 per-target bin entries beside the untouched dist/bin/<name>.js entry.
  • Claude-only build: a skill referencing ${CLAUDE_PLUGIN_ROOT}/bin/<name>.mjs lowers to a path the same artifact ships, and that file runs.
  • AB4766: claude: { bin: './host-bin' } shipping <name>.mjs fails the build before any artifact is written.
  • tests/adapter-capability-states.test.ts: every built-in target publishes cli + cliBin; a supported cli row without the layout is rejected at registration; no row is valid and hosts no bin.

@changeset-bot

changeset-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 9edd7ef

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
agent-bundle Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 3, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-03T11:47:51.201219Z fd20548 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4d57182936

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .changeset/387-artifact-routed-cli.md Outdated
Comment thread packages/agent-bundle/src/adapters/registry.ts Outdated
Comment thread packages/agent-bundle/src/adapters/registry.ts
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…ngeset PR reference

Codex review on #419: check the supported-`cli`-without-layout invariant
before the empty-layout early return, reject a `cliBin` layout that names
any directory but `bin` or omits `.mjs` (the compiler emits the routed CLI
only there), and end the changeset summary with the PR reference.
@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

@pkg-pr-new

pkg-pr-new Bot commented Sep 3, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle@419
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/create-agent-bundle@419
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/@agent-bundle/runtime@419

commit: fd20548

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d574883982

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .changeset/387-artifact-routed-cli.md Outdated
Comment thread packages/agent-bundle/src/build/cli-bins.ts Outdated
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…judgment; changeset patch

Codex review on #419: emission, the AB4765 warning, and the registration
invariant now use `componentCapabilities ?? capabilities` — the same judgment
`inspect` reports — via the new `TargetRegistry.componentCapabilityState` /
`hostsComponent` accessors, so a component override can never disagree with
what the artifact ships. The changeset is `patch` per the pre-1.0 policy
(minor is reserved for breaking changes).
@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: fdd8433f9e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…ngeset PR reference

Codex review on #419: check the supported-`cli`-without-layout invariant
before the empty-layout early return, reject a `cliBin` layout that names
any directory but `bin` or omits `.mjs` (the compiler emits the routed CLI
only there), and end the changeset summary with the PR reference.
@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…judgment; changeset patch

Codex review on #419: emission, the AB4765 warning, and the registration
invariant now use `componentCapabilities ?? capabilities` — the same judgment
`inspect` reports — via the new `TargetRegistry.componentCapabilityState` /
`hostsComponent` accessors, so a component override can never disagree with
what the artifact ships. The changeset is `patch` per the pre-1.0 policy
(minor is reserved for breaking changes).
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/387-artifact-routed-cli branch from fdd8433 to 664e79c Compare September 3, 2026 09:31
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

Reviewed commit: 664e79c1db

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…ngeset PR reference

Codex review on #419: check the supported-`cli`-without-layout invariant
before the empty-layout early return, reject a `cliBin` layout that names
any directory but `bin` or omits `.mjs` (the compiler emits the routed CLI
only there), and end the changeset summary with the PR reference.
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/387-artifact-routed-cli branch from 664e79c to bbd71c2 Compare September 3, 2026 10:05
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…judgment; changeset patch

Codex review on #419: emission, the AB4765 warning, and the registration
invariant now use `componentCapabilities ?? capabilities` — the same judgment
`inspect` reports — via the new `TargetRegistry.componentCapabilityState` /
`hostsComponent` accessors, so a component override can never disagree with
what the artifact ships. The changeset is `patch` per the pre-1.0 policy
(minor is reserved for breaking changes).
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Delightful!

Reviewed commit: bbd71c2d33

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…ngeset PR reference

Codex review on #419: check the supported-`cli`-without-layout invariant
before the empty-layout early return, reject a `cliBin` layout that names
any directory but `bin` or omits `.mjs` (the compiler emits the routed CLI
only there), and end the changeset summary with the PR reference.
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…judgment; changeset patch

Codex review on #419: emission, the AB4765 warning, and the registration
invariant now use `componentCapabilities ?? capabilities` — the same judgment
`inspect` reports — via the new `TargetRegistry.componentCapabilityState` /
`hostsComponent` accessors, so a component override can never disagree with
what the artifact ships. The changeset is `patch` per the pre-1.0 policy
(minor is reserved for breaking changes).
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/387-artifact-routed-cli branch 2 times, most recently from bbd71c2 to bffefff Compare September 3, 2026 10:30

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bffefff52e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/agent-bundle/src/build/cli-bins.ts Outdated
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…ngeset PR reference

Codex review on #419: check the supported-`cli`-without-layout invariant
before the empty-layout early return, reject a `cliBin` layout that names
any directory but `bin` or omits `.mjs` (the compiler emits the routed CLI
only there), and end the changeset summary with the PR reference.
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…judgment; changeset patch

Codex review on #419: emission, the AB4765 warning, and the registration
invariant now use `componentCapabilities ?? capabilities` — the same judgment
`inspect` reports — via the new `TargetRegistry.componentCapabilityState` /
`hostsComponent` accessors, so a component override can never disagree with
what the artifact ships. The changeset is `patch` per the pre-1.0 policy
(minor is reserved for breaking changes).
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…766)

Codex review on #419: a host-emitted `bin/MyPlugin.mjs` is the same file
as the generated `bin/myplugin.mjs` on macOS and Windows, so the collision
check folds case and names both paths in the diagnostic.
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/387-artifact-routed-cli branch from bffefff to 0949355 Compare September 3, 2026 10:45
@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: 094935584c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…ngeset PR reference

Codex review on #419: check the supported-`cli`-without-layout invariant
before the empty-layout early return, reject a `cliBin` layout that names
any directory but `bin` or omits `.mjs` (the compiler emits the routed CLI
only there), and end the changeset summary with the PR reference.
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…judgment; changeset patch

Codex review on #419: emission, the AB4765 warning, and the registration
invariant now use `componentCapabilities ?? capabilities` — the same judgment
`inspect` reports — via the new `TargetRegistry.componentCapabilityState` /
`hostsComponent` accessors, so a component override can never disagree with
what the artifact ships. The changeset is `patch` per the pre-1.0 policy
(minor is reserved for breaking changes).
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…766)

Codex review on #419: a host-emitted `bin/MyPlugin.mjs` is the same file
as the generated `bin/myplugin.mjs` on macOS and Windows, so the collision
check folds case and names both paths in the diagnostic.
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/387-artifact-routed-cli branch from 0949355 to 1c77d7c Compare September 3, 2026 11:14
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

Reviewed commit: 1c77d7cffa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…ngeset PR reference

Codex review on #419: check the supported-`cli`-without-layout invariant
before the empty-layout early return, reject a `cliBin` layout that names
any directory but `bin` or omits `.mjs` (the compiler emits the routed CLI
only there), and end the changeset summary with the PR reference.
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…judgment; changeset patch

Codex review on #419: emission, the AB4765 warning, and the registration
invariant now use `componentCapabilities ?? capabilities` — the same judgment
`inspect` reports — via the new `TargetRegistry.componentCapabilityState` /
`hostsComponent` accessors, so a component override can never disagree with
what the artifact ships. The changeset is `patch` per the pre-1.0 policy
(minor is reserved for breaking changes).
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…766)

Codex review on #419: a host-emitted `bin/MyPlugin.mjs` is the same file
as the generated `bin/myplugin.mjs` on macOS and Windows, so the collision
check folds case and names both paths in the diagnostic.
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/387-artifact-routed-cli branch from 1c77d7c to fd20548 Compare September 3, 2026 11:42
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

Reviewed commit: fd20548e89

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

#387)

Installed plugins ship skills, hooks, and script routes but had no way to run
the routed CLI without a separate npm install. Every target whose adapter
publishes the new `cli` capability (all built-in targets) now receives the
compiled command graph as `bin/<plugin-name>.mjs` (+ `-flight.mjs` worker),
run as `node <plugin-root>/bin/<plugin-name>.mjs`. Script routes reach it as
the `../bin/` sibling of their own `import.meta.url`; skills and hooks through
the plugin-root token. Manifest, validation (`cliBin` layout), `inspect`
(`cli` component), and `inspect --bundler` know the new directory; a target
without the capability omits the bin with AB4765; a host file colliding with
the bin path is AB4766. The npm package bin is unchanged.
…ngeset PR reference

Codex review on #419: check the supported-`cli`-without-layout invariant
before the empty-layout early return, reject a `cliBin` layout that names
any directory but `bin` or omits `.mjs` (the compiler emits the routed CLI
only there), and end the changeset summary with the PR reference.
…judgment; changeset patch

Codex review on #419: emission, the AB4765 warning, and the registration
invariant now use `componentCapabilities ?? capabilities` — the same judgment
`inspect` reports — via the new `TargetRegistry.componentCapabilityState` /
`hostsComponent` accessors, so a component override can never disagree with
what the artifact ships. The changeset is `patch` per the pre-1.0 policy
(minor is reserved for breaking changes).
The MCP App Rsbuild pass asserts the target root holds nothing but its own
HTML, so the routed CLI bin (like scripts, hooks, and MCP entries) must
follow it; otherwise a project combining MCP Apps with a generated CLI
failed with AB5000 (caught by the packed stdio projection release gate).
…766)

Codex review on #419: a host-emitted `bin/MyPlugin.mjs` is the same file
as the generated `bin/myplugin.mjs` on macOS and Windows, so the collision
check folds case and names both paths in the diagnostic.
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/387-artifact-routed-cli branch from fd20548 to 9edd7ef Compare September 3, 2026 12:09
@ScriptedAlchemy
ScriptedAlchemy merged commit 7afb328 into main Sep 3, 2026
5 checks passed
@ScriptedAlchemy
ScriptedAlchemy deleted the fix/387-artifact-routed-cli branch September 3, 2026 12:10
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
main (#419) emits src/cli/** as <target>/bin/<plugin-name>.mjs in every
built-in target. Package entries now covers the artifact bin, its state
anchor, how Skills, hooks, and scripts reach it, and AB4765/AB4766; the
artifact tree in Project structure shows the bin/ entry.
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
A conflict resolution took a pre-#419 copy of docs/diagnostics.md and
dropped the artifact-hosted routed CLI family main had added. The file is
main's again, plus the scoped exit-code preamble.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Routed CLI (src/cli/**) is only emitted into the npm package build, not into host artifacts — artifact scripts/skills cannot invoke it

1 participant